package org.springblade.modules.admin.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.lettuce.core.ScriptOutputType;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.ElevatorMaintainStatusEnums;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.MsgTypeEnum;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.vo.MaintainPlanConfigVO;
import org.springblade.modules.admin.vo.contract.ContractElevatorVo;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zcc
 * @version 1.0
 * @date 2022/3/7 15:47
 */

@Component
@Slf4j
public class ContractPlusJob {

	@Resource
	private IBuildingContractPlusService buildingContractPlusService;

	@Resource
	private IElevatorExtService elevatorExtService;

	@Resource
	private IMaintainPlanConfigService maintainPlanConfigService;


	@Resource
	private IElevatorEffectedService elevatorEffectedService;

	@Resource
	private IBuildingContractExtPlusService buildingContractExtPlusService;

	@Resource
	private IBuildingExtService buildingExtService;

	@Resource
	private IBuildingMaintainTimeService buildingMaintainTimeService;

	@Autowired
	private MaintainMsgService msgService;

	@Autowired
	private IUserService userService;

	@Autowired
	private IContractLogService contractLogService;

	@Autowired
	private IContractAgreeService contractAgreeService;

	@Autowired
	private MaintainMsgService maintainMsgService;


	/**
	 * 合同状态1:未生效2:已生效3:已到期4:已终止
	 */
	private final Integer[] status = {0, 1, 2, 3, 4};


	/**
	 * 合同扩展状态
	 * 1:待续签
	 * 2:已续签
	 * 3:即将到期
	 * 4:已脱保
	 * 5:已作废
	 */
	private final Integer[] status_ext = {0, 1, 2, 3, 4, 5};

	/**
	 * @Scheduled(cron = "0 0/1 * * * ?")
	 * 每天更新合同的状态是否到期
	 */
	@XxlJob(value = "updateContractStatus")
	public void updateContractStatus() {
		XxlJobHelper.handleSuccess("合同 job updateContractStatus 开始执行");
		try {

			//2024-03-12新增合同的服务信息同步到项目
			List<BuildingContractExtPlus> updateBuildingData = buildingContractExtPlusService.getUpdateBuildingData();
			synchroBuildingData(updateBuildingData);

			List<BuildingContractPlus> list = buildingContractPlusService.list(Wrappers.<BuildingContractPlus>lambdaQuery().eq(BuildingContractPlus::getDisDeleted, false));
			List<BuildingContractPlus> updateList = new ArrayList<>(20);
			for (BuildingContractPlus buildingContractPlus : list) {
				Date contractEndTime = buildingContractPlus.getContractEndTime();
				Date contractBeginTime = buildingContractPlus.getContractBeginTime();
				Date date = new Date();

				BuildingContractPlus buildingContractPlus2 = new BuildingContractPlus();
				buildingContractPlus2.setId(buildingContractPlus.getId());
				buildingContractPlus2.setStopTime(buildingContractPlus.getStopTime());
				//只判断审核通过的数据
				if (buildingContractPlus.getStatus().equals(status[2])) {
					if (buildingContractPlus.getContractExtStatus() != null && buildingContractPlus.getContractExtStatus().equals(status_ext[5])) {
						continue;
					}

					if (buildingContractPlus.getContractStatus() != null && buildingContractPlus.getContractStatus().equals(status[4])) {
						continue;
					}
					if (buildingContractPlus.getContractExtStatus() != null && buildingContractPlus.getContractExtStatus().equals(status_ext[4])) {
						continue;
					}

					//判断是否生效
					if (date.getTime() > contractBeginTime.getTime() && date.getTime() < contractEndTime.getTime() && !buildingContractPlus.getContractStatus().equals(status[2])) {
						if (!buildingContractPlus.getContractStatus().equals(status[2])) {
							buildingContractPlus2.setContractStatus(status[2]);
							contractLogService.saveLogHistory(104, buildingContractPlus, buildingContractPlus2);
						}
					}

					//判断是否即将到期-不等于已续签
					if (!buildingContractPlus.getContractExtStatus().equals(status_ext[2])) {
						if (DateUtil.betweenDay(date, contractEndTime, true) < 30L && !buildingContractPlus.getContractStatus().equals(status[3])) {
							if (!buildingContractPlus.getContractExtStatus().equals(status_ext[3])) {
								buildingContractPlus2.setContractExtStatus(status_ext[3]);
								contractLogService.saveLogHistory(102, buildingContractPlus, buildingContractPlus2);
							}
						}
					}

					//判断待续签
					if ((buildingContractPlus.getContractStatus().equals(status[3])) && (buildingContractPlus.getContractExtStatus().equals(status_ext[1]) || buildingContractPlus.getContractExtStatus().equals(status_ext[3]))) {
						if (!buildingContractPlus.getContractExtStatus().equals(status_ext[1])) {
							buildingContractPlus2.setContractExtStatus(status_ext[1]);
							contractLogService.saveLogHistory(101, buildingContractPlus, buildingContractPlus2);
						}
					}
					//判断待续签
					if ((buildingContractPlus.getContractStatus().equals(status[4])) && date.getTime() > buildingContractPlus.getStopTime().getTime() && (buildingContractPlus.getContractExtStatus().equals(status_ext[-1]) || buildingContractPlus.getContractExtStatus().equals(status_ext[3]))) {
						if (!buildingContractPlus.getContractExtStatus().equals(status_ext[1])) {
							buildingContractPlus2.setContractExtStatus(status_ext[1]);
							contractLogService.saveLogHistory(101, buildingContractPlus, buildingContractPlus2);
						}
					}

					//更新是否到期
					if (!buildingContractPlus.getContractStatus().equals(status[4]) && date.getTime() > contractEndTime.getTime() && !buildingContractPlus.getContractStatus().equals(status[3])) {
						if (!buildingContractPlus.getContractStatus().equals(status[3])) {
							buildingContractPlus2.setContractStatus(status[3]);
							buildingContractPlus2.setContractExtStatus(buildingContractPlus2.getContractExtStatus());
							contractLogService.saveLogHistory(105, buildingContractPlus, buildingContractPlus2);
						}
					}

				}
				if (buildingContractPlus2.getContractStatus() != null || buildingContractPlus2.getContractExtStatus() != null) {
					updateList.add(buildingContractPlus2);

				}

				//判断是否终止
				if (buildingContractPlus.getStopTime() != null) {
					if (date.getTime() > buildingContractPlus.getStopTime().getTime()) {
						buildingContractPlus2.setContractStatus(status[4]);
						//如果合同管理状态为-1或者3 表示没有操作过这个状态，更新为待续签
						if (buildingContractPlus.getContractExtStatus() == -1 || buildingContractPlus.getContractExtStatus().equals(status_ext[3])) {
							if (!buildingContractPlus.getContractExtStatus().equals(status_ext[1])) {
								buildingContractPlus2.setContractExtStatus(status_ext[1]);
								contractLogService.saveLogHistory(101, buildingContractPlus, buildingContractPlus2);
							}
						}
						if (buildingContractPlus2.getContractStatus() != null || buildingContractPlus2.getContractExtStatus() != null) {
							buildingContractPlusService.update(buildingContractPlus2);
						}
					}

				}
			}
			if (updateList.size() > 0) {
				List<List<BuildingContractPlus>> partition = Lists.partition(updateList, 20);
				for (List<BuildingContractPlus> list3 : partition) {
					buildingContractPlusService.updateBatchById(list3);
				}
			}
			XxlJobHelper.handleSuccess("合同更新状态job,updateContractStatus 任务方法 [执行]成功");
		} catch (Exception e) {
			e.printStackTrace();
			XxlJobHelper.handleFail("合同更新状态job,updateContractStatus [执行]失败:" + e);
		}


	}

	/**
	 * @Scheduled(cron = "0 0/1 * * * ?")
	 * 1: 按照合同的结束时间倒序排列，然后获取等于脱保并且结束时间最大-----更新为脱保
	 * 2: 获取第一条的结束时间,判断是否还有大于结束时间的合同 状态是未通过+时间最大  -----更新为拟定代保
	 * 3: 获取第一条的结束时间,判断是否还有大于结束时间的合同 取状态是通过（非脱保）+时间最大 -----更新为合同内，合同外
	 */
	@XxlJob(value = "updatePlanConfig")
	public void updatePlanConfig() {
		XxlJobHelper.handleSuccess("合同-电梯-维保状态(updatePlanConfig) 开始执行");
		try {
			List<MaintainPlanConfig> updateList = new ArrayList<>(100);
			//表示审核状态1:未审核，2:审核通过，3审核未通过
			Integer[] status = {0, 1, 2, 3};

			//合同扩展状态1:待续签2:已续签3:即将到期4:已脱保5:已作废
			Integer[] contractExtStatus = {0, 1, 2, 3, 4, 5};
			List<MaintainPlanConfig> planConfigList = maintainPlanConfigService.list();
			List<MaintainPlanConfig> planConfigList2 = JSON.parseArray(JSON.toJSONString(planConfigList), MaintainPlanConfig.class);
			List<ContractElevatorVo> contractElevatorVoList = buildingContractPlusService.getContractElevator();
			//排序处理
			for (ContractElevatorVo contractElevatorVo : contractElevatorVoList) {
				if (contractElevatorVo.getStopTime() != null) {
					contractElevatorVo.setIsStop(ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId());
					contractElevatorVo.setContractEndTime(contractElevatorVo.getStopTime());
				}
			}
			contractElevatorVoList = contractElevatorVoList.stream().sorted(new Comparator<ContractElevatorVo>() {
				@Override
				public int compare(ContractElevatorVo o1, ContractElevatorVo o2) {
					Date d1 = o1.getContractEndTime();
					Date d2 = o2.getContractEndTime();
					return d2.compareTo(d1);
				}
			}).collect(Collectors.toList());


			List<MaintainPlanConfig> epibolyList = new ArrayList(16);
			Map<Long, List<MaintainPlanConfig>> listMap1 = planConfigList.stream().collect(Collectors.groupingBy(MaintainPlanConfig::getElevatorId));
			Map<Long, List<MaintainPlanConfig>> listMap10 = planConfigList2.stream().collect(Collectors.groupingBy(MaintainPlanConfig::getElevatorId));
			if (planConfigList.size() > 0) {
				List<Long> elevatorIds = planConfigList.stream().map(MaintainPlanConfig::getElevatorId).distinct().collect(Collectors.toList());
				Map<Long, List<ContractElevatorVo>> listMap2 = contractElevatorVoList.stream().collect(Collectors.groupingBy(ContractElevatorVo::getElevatorId));
				for (Long elevatorId : elevatorIds) {
					MaintainPlanConfig maintainPlanConfig = listMap1.get(elevatorId).get(0);
					List<ContractElevatorVo> contractElevatorVos = listMap2.get(elevatorId);
					if (contractElevatorVos == null || contractElevatorVos.size() == 0) {
						//如果没有合同就更新无状态
						maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.NO_STATUS.getId());
						maintainPlanConfig.setContractId(-1L);
						maintainPlanConfigService.updateById(maintainPlanConfig);
						continue;
					}

					//判断条件1
					List<ContractElevatorVo> disUpdate1 = contractElevatorVos.stream().filter(o -> o.getContractExtStatus().equals(contractExtStatus[4])).collect(Collectors.toList());
					maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.NO_STATUS.getId());
					if (disUpdate1 != null && disUpdate1.size() > 0) {
						ContractElevatorVo contractElevatorVo = disUpdate1.get(0);
						maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.RELEASE_INSURANCE.getId());
						maintainPlanConfig.setContractId(contractElevatorVo.getId());
						maintainPlanConfig.setFromType(contractElevatorVo.getFromType());
						maintainPlanConfig.setFromTypeContractId(contractElevatorVo.getId());
						updateList.add(maintainPlanConfig);
						List<ContractElevatorVo> disUpdate2 = contractElevatorVos.stream().filter(o -> o.getContractEndTime().getTime() > contractElevatorVo.getContractEndTime().getTime() && o.getStatus().equals(status[1])).collect(Collectors.toList());
						if (disUpdate2 != null && disUpdate2.size() > 0) {
							maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.DIS_ENABLE.getId());
							maintainPlanConfig.setContractId(disUpdate2.get(0).getId());
							maintainPlanConfig.setFromType(disUpdate2.get(0).getFromType());
							maintainPlanConfig.setFromTypeContractId(disUpdate2.get(0).getId());
							updateList.remove(maintainPlanConfig);
							updateList.add(maintainPlanConfig);
						}
						List<ContractElevatorVo> disUpdate3 = contractElevatorVos.stream().filter(o -> o.getContractEndTime().getTime() > contractElevatorVo.getContractEndTime().getTime() && o.getStatus().equals(status[2])).collect(Collectors.toList());
						if (disUpdate3 != null && disUpdate3.size() > 0) {
							if (isExistContractByDates(disUpdate3).size() > 0) {
								maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId());
								maintainPlanConfig.setContractId(isExistContractByDates(disUpdate3).get(0).getId());
								maintainPlanConfig.setFromType(isExistContractByDates(disUpdate3).get(0).getFromType());
								maintainPlanConfig.setFromTypeContractId(isExistContractByDates(disUpdate3).get(0).getId());
								updateList.remove(maintainPlanConfig);
								updateList.add(maintainPlanConfig);
							} else {
								//判断是否有一份合同
								BuildingContractPlus next = buildingContractPlusService.getNext(maintainPlanConfig.getElevatorId());
								if (next != null) {
									maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId());
									maintainPlanConfig.setContractId(next.getId());
									maintainPlanConfig.setFromType(next.getFromType());
									maintainPlanConfig.setFromTypeContractId(next.getId());
									updateList.remove(maintainPlanConfig);
									updateList.add(maintainPlanConfig);
								} else {
									ContractElevatorVo elevatorVo = getLast(disUpdate3);
									maintainPlanConfig.setMaintainStatus(elevatorVo.getIsStop());
									maintainPlanConfig.setContractId(elevatorVo.getId());
									maintainPlanConfig.setFromType(elevatorVo.getFromType());
									maintainPlanConfig.setFromTypeContractId(elevatorVo.getId());
									updateList.remove(maintainPlanConfig);
									updateList.add(maintainPlanConfig);
								}
							}
						}
					} else {
						List<ContractElevatorVo> disUpdate2 = contractElevatorVos.stream().filter(o -> o.getStatus().equals(status[1])).collect(Collectors.toList());
						if (disUpdate2 != null && disUpdate2.size() > 0) {
							maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.DIS_ENABLE.getId());
							maintainPlanConfig.setContractId(disUpdate2.get(0).getId());
							maintainPlanConfig.setFromType(disUpdate2.get(0).getFromType());
							maintainPlanConfig.setFromTypeContractId(disUpdate2.get(0).getId());
							updateList.add(maintainPlanConfig);
						}
						List<ContractElevatorVo> disUpdate3 = contractElevatorVos.stream().filter(o -> o.getStatus().equals(status[2])).collect(Collectors.toList());
						if (disUpdate3 != null && disUpdate3.size() > 0) {
							if (isExistContractByDates(disUpdate3).size() > 0) {
								List<ContractElevatorVo> existContractByDates = isExistContractByDates(disUpdate3);
								maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId());
								maintainPlanConfig.setContractId(existContractByDates.get(0).getId());
								maintainPlanConfig.setFromType(existContractByDates.get(0).getFromType());
								maintainPlanConfig.setFromTypeContractId(existContractByDates.get(0).getId());
								updateList.add(maintainPlanConfig);
							} else {
								//判断是否有一份合同
								BuildingContractPlus next = buildingContractPlusService.getNext(maintainPlanConfig.getElevatorId());
								if (next != null) {
									maintainPlanConfig.setMaintainStatus(ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId());
									maintainPlanConfig.setContractId(next.getId());
									maintainPlanConfig.setFromType(next.getFromType());
									maintainPlanConfig.setFromTypeContractId(next.getId());
									updateList.remove(maintainPlanConfig);
									updateList.add(maintainPlanConfig);
								} else {
									ContractElevatorVo elevatorVo = getLast(disUpdate3);
									maintainPlanConfig.setMaintainStatus(elevatorVo.getIsStop());
									maintainPlanConfig.setContractId(elevatorVo.getId());
									maintainPlanConfig.setFromType(elevatorVo.getFromType());
									maintainPlanConfig.setFromTypeContractId(elevatorVo.getId());
									updateList.remove(maintainPlanConfig);
									updateList.add(maintainPlanConfig);
								}
							}
						}
					}

				}
			}
			List<List<MaintainPlanConfig>> listList = Lists.partition(updateList, 20);
			for (List<MaintainPlanConfig> list : listList) {
				List<MaintainPlanConfig> saveList = new ArrayList<>(20);
				for (int i = 0; i < list.size(); i++) {
					MaintainPlanConfig maintainPlanConfig1 = list.get(i);
					MaintainPlanConfig maintainPlanConfig2 = listMap10.get(maintainPlanConfig1.getElevatorId()).get(0);
					if (!maintainPlanConfig1.getMaintainStatus().equals(maintainPlanConfig2.getMaintainStatus()) || !maintainPlanConfig1.getContractId().equals(maintainPlanConfig2.getContractId())) {
						saveList.add(maintainPlanConfig1);
					}
				}
				if (saveList.size() > 0) {
					maintainPlanConfigService.updateBatchById(saveList);
				}

			}

			//更新外包，非外包
			List<List<MaintainPlanConfig>> listList2 = Lists.partition(epibolyList, 20);
			for (List<MaintainPlanConfig> list : listList2) {
				List<MaintainPlanConfig> saveList = new ArrayList<>(20);
				for (int i = 0; i < list.size(); i++) {
					MaintainPlanConfig maintainPlanConfig1 = list.get(i);
					MaintainPlanConfig maintainPlanConfig2 = listMap10.get(maintainPlanConfig1.getElevatorId()).get(0);
					if (!maintainPlanConfig1.getFromType().equals(maintainPlanConfig2.getFromType()) || !maintainPlanConfig1.getFromTypeContractId().equals(maintainPlanConfig2.getFromTypeContractId())) {
						saveList.add(maintainPlanConfig1);
					}
				}
				if (saveList.size() > 0) {
					maintainPlanConfigService.updateBatchById(saveList);
				}
			}


			XxlJobHelper.handleSuccess("合同-电梯-维保状态(updatePlanConfig)-[执行]成功");
		} catch (Exception e) {
			e.printStackTrace();
			XxlJobHelper.handleSuccess("合同-电梯-维保状态(updatePlanConfig)-[执行]失败" + e);
		}

	}


	/**
	 * @Scheduled(cron = "0 0 5 * * ?")
	 * 每天5点
	 * 插入当天有效梯Job
	 */
	@XxlJob(value = "elevatorEffectedJob")
	public void elevatorEffectedJob() {

		XxlJobHelper.handleSuccess("合同-保存有效电梯-方法(elevatorEffectedJob)-[执行]开始");
		try {
			elevatorEffectedService.effectedElevatorJob(DateUtil.date());
			XxlJobHelper.handleSuccess("合同-保存有效电梯-方法(elevatorEffectedJob)-[执行]成功");
		} catch (Exception e) {
			XxlJobHelper.handleSuccess("合同-保存有效电梯-方法(elevatorEffectedJob)-[执行]失败");
		}
	}


	/**
	 * @Scheduled(cron = "0 0/5 * * * ?")
	 * 每天早上1点发送梯无忧排班计划信息
	 */
	@XxlJob(value = "sendTwyContractMessage")
	public void sendTwyContractMessage() {
		XxlJobHelper.handleSuccess("梯无忧剩余排序和逾期风险消息...开始执行");
		//1:合同期内无剩余排期计划
		Integer type1 = 1;
		if (type1 == 1) {
			Query query = new Query();
			query.setCurrent(0);
			query.setSize(2);
			MaintainPlanConfigVO maintainPlanConfig = new MaintainPlanConfigVO();
			maintainPlanConfig.setIsPlan(0);
			maintainPlanConfig.setSearchMaintainStatus("2");
			IPage<MaintainPlanConfigVO> page = maintainPlanConfigService.selectMaintainPlanConfigPage(Condition.getPage(query), maintainPlanConfig);
			if (page.getTotal() > 0) {
				String tenantId = page.getRecords().get(0).getTenantId();
				List<User> userIds = userService.getUserListOfRoleCode("scheduling_elevators", tenantId);
				MaintainMsg maintainMsg = new MaintainMsg();
				maintainMsg.setTitle("合同期内无剩余排期");
				maintainMsg.setContent("存在" + page.getTotal() + "台电梯前在保(合同期内)，且无剩余排期，请及时关注");
				maintainMsg.setType(MsgTypeEnum.PLAN_NO.getId());
				maintainMsg.setTenantId(tenantId);
				msgService.sendMsg(maintainMsg, userIds.stream().map(User::getId).distinct().collect(Collectors.toList()), tenantId);
			}
		}
		//2:下次保养计划存在逾期风险
		Integer type2 = 2;
		if (type2 == 2) {
			Query query = new Query();
			query.setCurrent(0);
			query.setSize(2);
			MaintainPlanConfigVO maintainPlanConfig = new MaintainPlanConfigVO();
			maintainPlanConfig.setIsOverdueRisk(true);
			IPage<MaintainPlanConfigVO> page = maintainPlanConfigService.selectMaintainPlanConfigPage(Condition.getPage(query), maintainPlanConfig);
			if (page.getTotal() > 0) {
				String tenantId = page.getRecords().get(0).getTenantId();
				List<User> userIds = userService.getUserListOfRoleCode("scheduling_elevators", tenantId);
				MaintainMsg maintainMsg = new MaintainMsg();
				maintainMsg.setTitle("下次保养计划存在逾期⻛险");
				maintainMsg.setContent("存在" + page.getTotal() + "台年审梯，下次保养计划日期存在逾期⻛险，请及时关注");
				maintainMsg.setType(MsgTypeEnum.PLAN_NEXT.getId());
				maintainMsg.setTenantId(tenantId);
				msgService.sendMsg(maintainMsg, userIds.stream().map(User::getId).distinct().collect(Collectors.toList()), tenantId);
			}
		}
		XxlJobHelper.handleSuccess("梯无忧剩余排序和逾期风险消息...结束执行");
	}


	/**
	 * 发送合同电梯未排期的信息
	 */
	@XxlJob(value = "sendContractMessage")
	public void sendContractMessage() {
		XxlJobHelper.handleSuccess("合同管理:累计有合同电梯未排期....job开始执行");
		List<ElevatorContract> eles = contractAgreeService.notPlanEleHasContract(null);
		log.info(".................合同管理:累计有合同电梯未排期数量" + eles.size());
		if (eles.size() > 0) {
			List<String> tenantIds = eles.stream().map(ElevatorContract::getTenantId).distinct().collect(Collectors.toList());
			for (String tenantId : tenantIds) {
				eles = eles.stream().filter(o -> o.getTenantId().equals(tenantId)).collect(Collectors.toList());
				log.info(".................合同管理:结算的结果" + eles.size());
				List<Long> userIds = userService.getUserByRoleName(eles.get(0).getTenantId(), "admin");
				MaintainMsg maintainMsg = new MaintainMsg();
				maintainMsg.setTenantId(eles.get(0).getTenantId());
				maintainMsg.setContent("累计已有" + eles.size() + "电梯完成续保但未排期,请点击前往排期");
				maintainMsg.setTitle("累计已续保但未排期");
				maintainMsg.setType(MsgTypeEnum.HAS_CONTRACT_NO_PLAN.getId());
				maintainMsgService.sendMsg(maintainMsg, userIds, tenantId);
				XxlJobHelper.handleSuccess("合同管理:累计有合同电梯未排期....job执行结束");
			}
		}
	}

	/**
	 * 发送合同电梯未排期的信息--早上9点
	 */
	@XxlJob(value = "sendYesterdayContractMessage")
	public void sendYesterdayContractMessage() {
		XxlJobHelper.handleSuccess("合同管理:昨日有合同电梯未排期....job开始执行");
		List<ElevatorContract> eles = contractAgreeService.notPlanEleHasContract(DateUtil.yesterday());
		if (eles.size() > 0) {
			List<String> tenantIds = eles.stream().map(ElevatorContract::getTenantId).distinct().collect(Collectors.toList());
			for (String tenantId : tenantIds) {
				eles = eles.stream().filter(o -> o.getTenantId().equals(tenantId)).collect(Collectors.toList());
				List<Long> userIds = userService.getUserByRoleName(eles.get(0).getTenantId(), "admin");
				MaintainMsg maintainMsg = new MaintainMsg();
				maintainMsg.setTenantId(eles.get(0).getTenantId());
				maintainMsg.setContent("昨日已有" + eles.size() + "电梯完成续保但未排期,请点击前往排期");
				maintainMsg.setTitle("昨日已续保但未排期");
				maintainMsg.setType(MsgTypeEnum.HAS_CONTRACT_NO_PLAN_YES.getId());
				maintainMsgService.sendMsg(maintainMsg, userIds, tenantId);
			}
		}
		XxlJobHelper.handleSuccess("合同管理:昨日有合同电梯未排期....job执行结束");
	}

	@XxlJob(value = "updateContractEndTime")
	public void updateEndTime() {
		List<BuildingContractPlus> updateEndTimeList = buildingContractPlusService.getUpdateEndTimeList();
		for (BuildingContractPlus buildingContractPlus : updateEndTimeList) {
			buildingContractPlus.setAboutEndDay(-1);
			buildingContractPlus.setEndDay(-1);
			buildingContractPlus.setDisCheckDay(0);
			Date endTime = Convert.toDate(buildingContractPlus.getStopTime(), buildingContractPlus.getContractEndTime());
			Integer days = Convert.toInt(DateUtil.betweenDay(new Date(), endTime, true));
			if (endTime.getTime() > System.currentTimeMillis()) {
				buildingContractPlus.setAboutEndDay(days);
			}
			if (endTime.getTime() < System.currentTimeMillis()) {
				buildingContractPlus.setEndDay(days);
			}
			//表示未审核
			Integer status = 1;
			if (buildingContractPlus.getStatus().equals(status)) {
				Integer day = Convert.toInt(DateUtil.betweenDay(new Date(), Convert.toDate(buildingContractPlus.getCheckTime(), buildingContractPlus.getCreateTime()), true));
				buildingContractPlus.setDisCheckDay(day);
			}
		}
		List<List<BuildingContractPlus>> partition = Lists.partition(updateEndTimeList, 20);
		for (List<BuildingContractPlus> updateList : partition) {
			buildingContractPlusService.updateBatchById(updateList);
		}
	}

	/**
	 * 同步合同服务信息到项目里面
	 *
	 * @param updateBuildingData 待同步的合同数据
	 */
	private void synchroBuildingData(List<BuildingContractExtPlus> updateBuildingData) {
		if (updateBuildingData.size() > 0) {

			List<BuildingExt> buildingExtUpdates = new ArrayList<>(16);
			List<BuildingMaintainTime> buildingMaintainTimes = new ArrayList<>(16);
			List<Long> buildingIds = updateBuildingData.stream().map(BuildingContractExtPlus::getBuildingId).distinct().collect(Collectors.toList());
			List<BuildingExt> buildingExtList = buildingExtService.list(Wrappers.<BuildingExt>lambdaQuery().in(BuildingExt::getBuildingId, buildingIds));
			Map<Long, List<BuildingExt>> listMap = buildingExtList.stream().collect(Collectors.groupingBy(BuildingExt::getBuildingId));
			//表示已经同步
			Integer status = 1;
			for (BuildingContractExtPlus buildingContractExtPlus : updateBuildingData) {
				buildingContractExtPlus.setStatus(status);
				List<BuildingExt> buildingExts = listMap.get(buildingContractExtPlus.getBuildingId());
				if (buildingExts != null && buildingExts.size() > 0) {
					BuildingExt buildingExt = buildingExts.get(0);
					buildingExt.setMaintainPersonnel(buildingContractExtPlus.getMaintainPersonnel());
					buildingExt.setMakeAppointment(buildingContractExtPlus.getMakeAppointment());
					buildingExt.setAllowMaintain(buildingContractExtPlus.getAllowMaintain());
					buildingExt.setAllowMaintainImm(buildingContractExtPlus.getAllowMaintainImm());
					buildingExt.setRescueTime(buildingContractExtPlus.getRescueTime());
					buildingExt.setRescueDaytime(buildingContractExtPlus.getRescueDaytime());
					buildingExt.setRescueNight(buildingContractExtPlus.getRescueNight());
					buildingExt.setStagnationPoint(buildingContractExtPlus.getStagnationPoint());
					buildingExt.setMalfunctionWorkTimeType(buildingContractExtPlus.getMalfunctionWorkTimeType());
					buildingExt.setMalfunctionWorkArrivalTime(buildingContractExtPlus.getMalfunctionWorkArrivalTime());
					buildingExt.setMalfunctionWorkRenewTime(buildingContractExtPlus.getMalfunctionWorkRenewTime());
					buildingExtUpdates.add(buildingExt);
				} else {
					BuildingExt buildingExt = new BuildingExt();
					BeanUtil.copyProperties(buildingContractExtPlus, buildingExt);
					buildingExt.setId(null);
					buildingExtUpdates.add(buildingExt);
				}
				//保存时间
				List<BuildingContractMaintainTime> buildingContractMaintainTimes = buildingContractExtPlus.getBuildingContractMaintainTimes();
				for (BuildingContractMaintainTime buildingContractMaintainTime : buildingContractMaintainTimes) {
					BuildingMaintainTime buildingMaintainTime = new BuildingMaintainTime();
					BeanUtil.copyProperties(buildingContractMaintainTime, buildingMaintainTime);
					buildingMaintainTime.setId(null);
					buildingMaintainTimes.add(buildingMaintainTime);
				}
			}
			List<List<BuildingExt>> partition1 = ListUtil.partition(buildingExtUpdates, 20);
			List<List<BuildingMaintainTime>> partition2 = ListUtil.partition(buildingMaintainTimes, 20);
			List<List<BuildingContractExtPlus>> partition3 = ListUtil.partition(updateBuildingData, 20);
			buildingMaintainTimeService.remove(Wrappers.<BuildingMaintainTime>lambdaQuery().in(BuildingMaintainTime::getBuildingId, buildingIds));
			for (List<BuildingExt> updateList : partition1) {
				buildingExtService.saveOrUpdateBatch(updateList);
			}
			for (List<BuildingMaintainTime> updateList : partition2) {
				buildingMaintainTimeService.saveOrUpdateBatch(updateList);
			}
			for (List<BuildingContractExtPlus> updateList : partition3) {
				buildingContractExtPlusService.updateBatchById(updateList);
			}

		}

	}

	/**
	 * 判断是否在合同范围内，有一个满足返回true
	 *
	 * @param elevatorContracts 电梯合同
	 * @return 状态
	 */
	private List<ContractElevatorVo> isExistContractByDates(List<ContractElevatorVo> elevatorContracts) {
		List<ContractElevatorVo> resultList = new ArrayList<>(5);
		for (ContractElevatorVo elevatorContract : elevatorContracts) {
			if (elevatorContract.getStopTime() != null) {
				elevatorContract.setContractEndTime(elevatorContract.getStopTime());
			}
			Date contractBeginTime = elevatorContract.getContractBeginTime();
			Date contractEndTime = elevatorContract.getContractEndTime();
			Date beginDate = new Date();
			if (beginDate.getTime() >= contractBeginTime.getTime() && beginDate.getTime() <= contractEndTime.getTime()) {
				resultList.add(elevatorContract);
			}
		}
		return resultList;
	}


	/**
	 * 获取上一份合同
	 *
	 * @param elevatorContracts
	 * @return
	 */
	private ContractElevatorVo getLast(List<ContractElevatorVo> elevatorContracts) {
		for (ContractElevatorVo elevatorContract : elevatorContracts) {
			if (elevatorContract.getStopTime() != null) {
				elevatorContract.setContractEndTime(elevatorContract.getStopTime());
				elevatorContract.setIsStop(5);
			}
		}
		elevatorContracts = elevatorContracts.stream().sorted(new Comparator<ContractElevatorVo>() {
			@Override
			public int compare(ContractElevatorVo o1, ContractElevatorVo o2) {
				Date d1 = o1.getContractEndTime();
				Date d2 = o2.getContractEndTime();
				return d2.compareTo(d1);
			}
		}).collect(Collectors.toList());
		return elevatorContracts.get(0);
	}

}
